package com.hugedata.cdn.util;

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.apache.log4j.Logger;

/**
 * 
 * 项目名称：cdn 类名称：FileTool 类描述： 创建人：zhaoaihua 创建时间�?013-3-23 下午7:21:50 修改备注�?
 * 
 * @version
 * 
 */
public abstract class FileTool
{
    private static Logger logger = Logger.getLogger(FileTool.class);

    private static final int BUFFER_SIZE = 8192;

    /**
     * <默认构�?函数>
     */
    protected FileTool()
    {
    }

    /**
     * 加载类资�?
     * 
     * @param path
     *            类路�?
     * @return 资源
     * @throws FileNotFoundException
     *             指定的资源找不到
     */
    public InputStream loadInputStreamByClassPath(String path)
            throws FileNotFoundException
    {

        ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();

        InputStream stream = classLoader.getResourceAsStream(path);

        if (stream == null)
        {
            throw new FileNotFoundException(path + " not found on classpath.");
        }

        return stream;
    }

    /**
     * 将单个源文件拷贝到目标文�?
     * 
     * @param srcFile
     *            源文�?
     * @param objFile
     *            目标文件
     * @throws IOException
     *             发生文件读写错误
     */
    public void copySingleFile(File srcFile, File objFile) throws IOException
    {
        InputStream in = null;
        OutputStream out = null;
        try
        {
            in = new FileInputStream(srcFile);
            out = new FileOutputStream(objFile);
            write(in, out);
            out.flush();
        }
        finally
        {
            closeStream(in);
            closeStream(out);
        }
    }

    /**
     * 关闭流资�?
     * 
     * @param closeable
     *            流资�?
     */
    public void closeStream(Closeable closeable)
    {
        if (closeable != null)
        {
            try
            {
                closeable.close();
            }
            catch (IOException e)
            {
                logger.error("closeStream Failed.");
            }
        }
    }

    /**
     * 将输入流的数据写入到输出�?
     * 
     * @param in
     *            输入�?
     * @param out
     *            输出�?
     * @throws IOException
     *             发生IO错误
     */
    public void write(InputStream in, OutputStream out) throws IOException
    {
        byte[] bytes = new byte[BUFFER_SIZE];
        for (int readSize; (readSize = in.read(bytes)) != -1;)
        {
            out.write(bytes, 0, readSize);
        }
    }

    /**
     * 创建�?��目录
     * 
     * @param parentFile
     *            父目录路�?
     * @param child
     *            子目录名�?
     * @throws IOException
     *             创建失败
     */
    public void createDirectory(File parentFile, String child)
            throws IOException
    {
        File file = new File(parentFile, child);
        if (!file.exists())
        {
            if (!file.mkdirs())
            {
                throw new IOException("File " + file
                        + " mkdirs failed, please check it.");
            }
        }
    }

    /**
     * 获取远程目录下的文件列表
     * 
     * @param folderName
     *            文件夹的名字
     * @return 返回字符串数�?
     */
    public String[] getFileList(String folderName)
    {
        File folder = new File(folderName);

        String[] fileArray = folder.list();

        return fileArray;
    }

    /**
     * 文件的移�?
     * 
     * @param oPath
     *            原始路径
     * @param nPath
     *            新路�?
     * @see [类�?�?方法、类#成员]
     */
    public void moveFile(String oPath, String nPath)
    {
        File oldPath = new File(oPath);
        File newPath = new File(nPath);

        // 判断当前的文件是否存在如果存在则先删除在覆盖
        delFile(nPath);

        // 移动文件
        boolean bool = oldPath.renameTo(newPath);
        if (!bool)
        {

            moveFileHandle(oldPath, newPath.getPath());
        }
    }

    /**
     * 文件的删�?
     * 
     * @param nPath
     *            新路�?
     * @see [类�?�?方法、类#成员]
     */
    public void delFile(String nPath)
    {
        File newPath = new File(nPath);

        if (newPath.exists())
        {

            boolean bool = newPath.delete();

            if (!bool)
            {

                logger.error("File Delete Failed , Delete file path: " + nPath);
            }
        }
    }

    /**
     * 移动文件失败记录日志
     * 
     * @param file
     *            原始文件
     * @param newpath
     *            新文�?
     * @see [类�?�?方法、类#成员]
     */
    public void moveFileHandle(File file, String newpath)
    {

        logger.error("File Move Failed , Old Path File Address is : "
                + file.getPath() + ", New Path File Address is : " + newpath);
    }

    /**
     * 生成jar文件
     * 
     * @param clazz
     * @param fileName
     * @return
     */
    public File createJar(Class<?> clazz, String fileName)
    {
        String filePath = ".";
        if (null != System.getProperty("webapp.root"))
        {
            filePath = System.getProperty("webapp.root") + "META-INF";
        }

        logger.debug("create jar file ,name=" + fileName);
        try
        {
            String pathName = clazz.getPackage().getName().replace(".", "/");
            // final String fileName =
            // clazz.getName().substring(clazz.getName().lastIndexOf(".")+1);
            final File file = File.createTempFile(fileName, ".jar", new File(
                    filePath));
            Manifest manifest = new Manifest();
            manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
            manifest.getMainAttributes().putValue("Created-By", "ejtoo");
            JarOutputStream out = new JarOutputStream(
                    new FileOutputStream(file), manifest);

            File dir = new File(clazz.getResource("").getFile());
            File[] names = dir.listFiles();
            for (File name : names)
            {
                JarEntry entry = new JarEntry(pathName + "/" + name.getName());
                out.putNextEntry(entry);
                FileInputStream in = new FileInputStream(name);
                byte[] buffer = new byte[1024];
                int n = in.read(buffer);
                while (n != -1)
                {
                    out.write(buffer, 0, n);
                    n = in.read(buffer);
                }
                in.close();
            }
            out.flush();
            out.close();
            logger.info("create jar file success,fileName=" + file.getName());
            return file;
        }
        catch (IOException e)
        {
            logger.error(
                    "create jar file fail,fileName=" + fileName + " ."
                            + e.getMessage(), e);
            return null;
        }
    }
}
